#include "factory.h"
#include "head.h"
#include "work_que.h"
#include "tcp_epoll_op.h"
#include "database_op.h"
#include "normal_com.h"
#include "trans_file.h"
#include "login.h"
int exit_fds[2];//创建无名管道
//退出机制信号处理函数
void sig_exit_func(int signum){
    write(exit_fds[1],&signum,1);
}
int main(int argc,char** argv)
{
    if(argc!=5){
        printf("./thread_pool_server IP PORT THREAD_NUM CAPACITY");
        return -1;
    }
    pipe(exit_fds);
    if(fork()){//这里是父进程，用来协助完成退出机制
        close(exit_fds[0]);//父进程关闭读端，然后自定义退出信号并等待子进程运行结束。
        signal(SIGUSR1,sig_exit_func);
        wait(NULL);
        return 0;
    }
    close(exit_fds[1]);//子进程关闭写端
    Factory_t f;//主数据结构
    int thread_num=atoi(argv[3]);
    int capacity=atoi(argv[4]);
    factory_init(&f,thread_num,capacity);
    factory_start(&f,thread_num);
    normal_Que_t nq;
    bzero(&nq,sizeof(normal_Que_t));
    int socket_fd;
    tcp_init(&socket_fd,argv[1],argv[2]);//自定义函数
    //接收请求，加锁，放入队列，解锁，signal
    int new_fd;
    struct sockaddr_in client_addr;
    train_state_t t;
    train_t nt;
    //epoll注册监控socket_fd,exit_fd[0]
    int epfd=epoll_create(1);
    struct epoll_event evs[50];
    epoll_add(epfd,exit_fds[0]);
    epoll_add(epfd,socket_fd);
    int ready_fd_num,i,j;
    while(1){
        ready_fd_num=epoll_wait(epfd,evs,50,-1);
        for(i=0;i<ready_fd_num;i++){
            if(evs[i].data.fd==socket_fd){
                bzero(&client_addr,sizeof(client_addr));
                socklen_t addr_len=sizeof(client_addr);
                //accept就完成了三次握手，如果一个人都没过来连接的话，则卡住睡眠
                new_fd=accept(socket_fd,(struct sockaddr*)&client_addr,&addr_len);
                printf("%s %d is connect\n",inet_ntoa(client_addr.sin_addr),ntohs(client_addr.sin_port));
                bzero(&t,sizeof(train_state_t));
                int ret=do_register_or_login_or_token(new_fd,&f,&t,&nq);
                if(ret==-1){
                    continue;
                }
                if(ret==1){
                    epoll_add(epfd,new_fd);//只监控普通new_fd,不监控用于文件传输的new_fd
                    send_session(new_fd,&t,TOKEN,((nq.que_tail)->token));  
                }
            }else if(evs[i].data.fd==exit_fds[0]){//线程池要退出了
                        for(j=0;j<thread_num;j++){//给每一个子线程发送cancel信号
                            pthread_cancel(f.pthid[j]);
                            printf("cancel success\n");
                        }
                        for(j=0;j<thread_num;j++){//等待每一个子线程
                            pthread_join(f.pthid[j],NULL);
                        }
                        exit(0);
            }else {
                //先确定来消息的对象是哪一个new_fd
                pClient_State_t ptemp=nq.que_head;
                for(;ptemp&&evs[i].data.fd!=ptemp->new_fd;ptemp=ptemp->next);
                //进行指令解析
                if(ptemp!=NULL){
                    bzero(&nt,sizeof(train_t));
                    recv_session(ptemp->new_fd,&t);
                    if(t.state==CD){//cd支持根，上一级，目录
                        do_cd(ptemp,&t,&nt);
                    }else if(t.state==LS){
                        do_ls(ptemp,&t,&nt);//当前目录
                    }else if(t.state==PWD){
                        do_pwd(ptemp,&t,&nt);
                    }else if(t.state==REMOVE){
                        do_remove(ptemp,&t,&nt);
                    }else if(t.state==0){//如果对端断开则关闭其对应缓冲区
                        printf("byebye\n");
                        epoll_del(epfd,ptemp->new_fd);
                        close(ptemp->new_fd);
                    }else{
                    }
                }
            }  
        }
    }
    return 0;
}
